package com.example.wechatscancode.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import androidx.annotation.NonNull;

import com.example.wechatscancode.bean.IBean;


import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


public class HttpsUtils {
    private static final String TAG = "HttpsUtils";
    private static String BOUNDARY = "----WebKitFormBoundaryDwvXSRMl0TBsL6kW"; // 定义数据分隔线


    public static boolean sSMS = false;

    public interface OnResultFromWeb {
        void onResult(String className, IBean bean);

        void onResult(Map<String, IBean> mapBean);

        void onResult(Bitmap bitmap);   // 返回二维码bitmap

        void onResult(String str);
    }

    public static class OnResultFromWebImpl implements OnResultFromWeb {
        @Override
        public void onResult(String className, IBean bean) {
        }

        @Override
        public void onResult(Map<String, IBean> mapBean) {
        }

        @Override
        public void onResult(Bitmap bitmap) {
        }

        @Override
        public void onResult(String str) {

        }
    }


    /************************************************随访箱 项目使用的GET请求**************************/
    /**
     * GET请求
     *
     * @param url
     * @param bean
     * @param onResultFromWeb
     */
    public static void returnBeanFromWeb_get(@NonNull final String url, final IBean bean, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        Map<String, IBean> newMap = new HashMap<>();
        newMap.put(url, bean);
        returnBeansFromWeb_get(newMap, onResultFromWeb);
    }


    public static void returnBeansFromWeb_get(@NonNull final Map<String, IBean> beanMap, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        Map<String, String> mapRequestP = new HashMap<>();
        mapRequestP.put("requested-with", "android");
        getBeansFromWeb_get(beanMap, mapRequestP, onResultFromWeb);
    }


/************************************************随访箱 项目使用的POST请求**************************/
    /**
     * 此方法用于随诊箱
     *
     * @param url             服务器全路径
     * @param bean            序列化、反序化对象
     * @param onResultFromWeb
     */
    public static void returnBeanFromWeb_post(@NonNull final String url, final IBean bean, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        Map<String, IBean> newMap = new HashMap<>();
        newMap.put(url, bean);
        returnBeansFromWeb_post(newMap, onResultFromWeb);
    }


    /**
     * 此方法用于随诊箱
     *
     * @param beanMap
     * @param onResultFromWeb
     */
    public static void returnBeansFromWeb_post(@NonNull final Map<String, IBean> beanMap, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        String requestParamkey = "jsonBean";
        Map<String, String> mapRequestP = new HashMap<>();
        mapRequestP.put("requested-with", "android");
        mapRequestP.put("Content-Type", "application/x-www-form-urlencoded");
        getBeansFromWeb_post(beanMap, requestParamkey, mapRequestP, onResultFromWeb);
    }


    /**
     * 沙发请求二维码(第三方)
     *
     * @param maps
     * @param onResultFromWeb
     */
    public static void returnQRCodeFromWeb_Post(@NonNull final Map<String, IBean> maps, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        Map<String, String> mapRequestP = new HashMap<>();
        mapRequestP.put("Content-Type", "application/json");
        getBeansFromWeb_post(maps, null, mapRequestP, onResultFromWeb);
    }


    /**
     * 这是沙发获取二维码图片接口  (特殊处理)
     *
     * @param strUrlPath url地址
     * @return 请求的响应数据
     */
    private static Bitmap submitGetData_BitmapOfQRCode(String strUrlPath) throws Exception {
        // 创建URL对象
        URL url = new URL(strUrlPath);

        Log.e(TAG, "request url: " + strUrlPath);

        // 打开连接 获取连接对象
        URLConnection connection = url.openConnection();
        connection.setConnectTimeout(6000);

        //设置 安卓端flag
        connection.setRequestProperty("requested-with", "android");

        return BitmapFactory.decodeStream(connection.getInputStream());
    }


    /*****************************************下面方法需要修改请通知******************************************/


    /**
     * GET请求
     *
     * @param beanMap
     * @param onResultFromWeb
     */
    private static void getBeansFromWeb_get(@NonNull final Map<String, IBean> beanMap, final Map<String, String> requsetProperties, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        final Map<String, IBean> responseBeanMap = new HashMap<>();
        final Iterator<Map.Entry<String, IBean>> entries = beanMap.entrySet().iterator();

        while (entries.hasNext()) {
            final Map.Entry<String, IBean> entry = entries.next();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String className = "";
                    try {
                        className = entry.getValue().getClass().getSimpleName();
                        String url_get = entry.getKey();
                        Log.e(TAG, "request url: " + url_get);

                        String json = submitGetData(url_get, requsetProperties);
                        Log.e(TAG, "response json: " + json);
                        IBean clazz = JsonSeriaUtil.beanFromJson(json, entry.getValue().getClass());
                        responseBeanMap.put(className, clazz);
                        onResultFromWeb.onResult(className, clazz);
                    } catch (Exception e) {
                        e.printStackTrace();
                        responseBeanMap.put(className, null);
                        onResultFromWeb.onResult(className, null);
                    }
                    onResultFromWeb.onResult(responseBeanMap);
                }
            }).start();
        }
    }


    /**
     * POST请求
     *
     * @param beanMap         String: 服务器全路径 IBean: 序列化、反序化对象
     * @param onResultFromWeb
     */
    private static void getBeansFromWeb_post(@NonNull final Map<String, IBean> beanMap, final String requestParamkey, final Map<String, String> requsetProperties, @NonNull final OnResultFromWebImpl onResultFromWeb) {
        final Map<String, IBean> responseBeanMap = new HashMap<>();
        final Iterator<Map.Entry<String, IBean>> entries = beanMap.entrySet().iterator();
        while (entries.hasNext()) {
            final Map.Entry<String, IBean> entry = entries.next();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    String className = "";
                    try {
                        className = entry.getValue().getClass().getSimpleName();
                        Log.e(TAG, "request url: " + entry.getKey());

                        String json = JsonSeriaUtil.beanToJson(entry.getValue());
                        Log.e(TAG, "request json: " + json);

                        if (sSMS) {
                            json = AESUtil.encrypt(json);
                            Log.e(TAG, "request json: " + json);
                        }

                        Map<String, String> mapParams = null;

                        if (requestParamkey != null) {
                            mapParams = new HashMap<>();
//                        mapParams.put("jsonBean", json);
                            mapParams.put(requestParamkey, json);
                            json = submitPostData(entry.getKey(), mapParams, null, requsetProperties);
                        } else {
                            json = submitPostData(entry.getKey(), null, json, requsetProperties);
                        }

//                        Map<String, String> mapRequestP = new HashMap<>();
//                        mapRequestP.put("requested-with", "android");
//                        mapRequestP.put("Content-Type", "application/x-www-form-urlencoded");


                        Log.e(TAG, "response json: " + json);
                        IBean clazz = JsonSeriaUtil.beanFromJson(json, entry.getValue().getClass());
                        responseBeanMap.put(className, clazz);
                        onResultFromWeb.onResult(className, clazz);
                    } catch (Exception e) {
                        e.printStackTrace();
                        responseBeanMap.put(className, null);
                        onResultFromWeb.onResult(className, null);
                    }
                    onResultFromWeb.onResult(responseBeanMap);
                }
            }).start();
        }
    }


    /**
     * @param strUrlPath
     * @param params           params != null 代表form方式POST请求  有对应的请求key
     * @param param            params == null   param != null    二进制上传， 没有对应的请求key
     * @param requestPropertys 请求头
     * @return
     * @throws Exception
     */
    private static String submitPostData(@NonNull String strUrlPath, Map<String, String> params, String param, @NonNull Map<String, String> requestPropertys) throws Exception {
        byte[] requestBodyData;
        if (params == null) {
            requestBodyData = param.getBytes("UTF-8");
        } else {
            requestBodyData = getRequestBodyData(params, "UTF-8");  // form方式POST
        }


        URL url = new URL(strUrlPath);

        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setConnectTimeout(6000);     //设置连接超时时间
        httpURLConnection.setDoInput(true);                  //打开输入流，以便从服务器获取数据
        httpURLConnection.setDoOutput(true);                 //打开输出流，以便向服务器提交数据
        httpURLConnection.setRequestMethod("POST");     //设置以Post方式提交数据
        httpURLConnection.setUseCaches(false);               //使用Post方式不能使用缓存

//        //设置请求体的类型是文本类型
//        httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
////        httpURLConnection.setRequestProperty("Content-Type", "application/json");
//        //设置请求体的长度
        httpURLConnection.setRequestProperty("Content-Length", String.valueOf(requestBodyData.length));
//        //设置 安卓端flag
//        httpURLConnection.setRequestProperty("requested-with", "android");


        for (Map.Entry<String, String> entry : requestPropertys.entrySet()) {
            httpURLConnection.setRequestProperty(entry.getKey(), entry.getValue());
        }

        //获得输出流，向服务器写入数据
        OutputStream outputStream = httpURLConnection.getOutputStream();

        outputStream.write(requestBodyData);

        int responseCode = httpURLConnection.getResponseCode();              //获得服务器的响应码

        if (responseCode == HttpURLConnection.HTTP_OK) {
            InputStream inptStream = httpURLConnection.getInputStream();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] outData = new byte[1024];
            int len = 0;
            while ((len = inptStream.read(outData)) != -1) {
                byteArrayOutputStream.write(outData, 0, len);
            }
            return new String(byteArrayOutputStream.toByteArray());
        }

        return null;
    }


    /**
     * 使用GET方法读取http中的数据
     *
     * @param strUrlPath url地址
     * @return 请求的响应数据
     */
    public static String submitGetData(String strUrlPath, @NonNull Map<String, String> requestPropertys) throws Exception {
        // 创建URL对象
        URL url = new URL(strUrlPath);
        // 打开连接 获取连接对象
        URLConnection connection = url.openConnection();
        connection.setConnectTimeout(6000);

        if (requestPropertys != null) {
            //设置 安卓端flag
            for (Map.Entry<String, String> entry : requestPropertys.entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }

        // 从连接对象中获取网络连接中的输入字节流对象
        InputStream inputStream = connection.getInputStream();
        // 将输入字节流包装成输入字符流对象,并进行字符编码
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
        // 创建一个输入缓冲区对象，将字符流对象传入
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        // 定义一个字符串变量，用来接收输入缓冲区中的每一行字符串数据
        String line;
        // 创建一个可变字符串对象，用来装载缓冲区对象的数据，使用字符串追加的方式，将响应的所有数据都保存在该对象中
        StringBuilder stringBuilder = new StringBuilder();
        // 使用循环逐行读取输入缓冲区的数据，每次循环读入一行字符串数据赋值给line字符串变量，直到读取的行为空时标识内容读取结束循环
        while ((line = bufferedReader.readLine()) != null) {
            // 将从输入缓冲区读取到的数据追加到可变字符对象中
            stringBuilder.append(line);
        }
        // 依次关闭打开的输入流
        bufferedReader.close();
        inputStreamReader.close();
        inputStream.close();
        // 将可变字符串转换成String对象返回
        return stringBuilder.toString();
    }

    public static void SetFile_returnBeanFromWeb_post(String urlstr, Map<String, String> map, Map<String, File> files, @NonNull final OnResultFromWebImpl onResultFromWeb) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                String BOUNDARY = "----WebKitFormBoundaryDwvXSRMl0TBsL6kW"; // 定义数据分隔线

                URL url = null;
                HttpURLConnection connection = null;
                try {
                    url = new URL(urlstr);
                    Log.e(TAG, "request url: " + urlstr);
                    connection = (HttpURLConnection) url.openConnection();
                    // 发送POST请求必须设置如下两行
                    connection.setDoOutput(true);
                    connection.setDoInput(true);
                    connection.setUseCaches(false);
                    connection.setRequestMethod("POST");
                    connection.setRequestProperty("Accept", "*/*");
                    connection.setRequestProperty("connection", "Keep-Alive");
                    connection.setRequestProperty("user-agent", "Android WYJ");
                    connection.setRequestProperty("Charsert", "UTF-8");
                    connection.setRequestProperty("requested-with", "android");
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    connection.setRequestProperty("Accept-Encoding", "gzip,deflate");
                    connection.setRequestProperty("Content-Type",
                            "multipart/form-data; boundary=" + BOUNDARY);

                    OutputStream out = new DataOutputStream(connection.getOutputStream());
                    byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();// 定义最后数据分隔线

                    // 文件
                    if (files != null && !files.isEmpty()) {
                        for (Map.Entry<String, File> entry : files.entrySet()) {
                            File file = entry.getValue();
                            String fileName = entry.getKey();

                            StringBuilder sb = new StringBuilder();
                            sb.append("--");
                            sb.append(BOUNDARY);
                            sb.append("\r\n");
                            sb.append("Content-Disposition: form-data;name=\"" + fileName
                                    + "\";filename=\"" + file.getName() + "\"\r\n");
                            sb.append("Content-Type: image/jpg\r\n\r\n");
                            byte[] data = sb.toString().getBytes();
                            out.write(data);

                            DataInputStream in = new DataInputStream(new FileInputStream(
                                    file));
                            int bytes = 0;
                            byte[] bufferOut = new byte[1024];
                            while ((bytes = in.read(bufferOut)) != -1) {
                                out.write(bufferOut, 0, bytes);
                            }
                            out.write("\r\n".getBytes()); // 多个文件时，二个文件之间加入这个
                            in.close();
                        }
                    }
                    // 数据参数
                    if (map != null && !map.isEmpty()) {

                        for (Map.Entry<String, String> entry : map.entrySet()) {
                            StringBuilder sb = new StringBuilder();
                            sb.append("--");
                            sb.append(BOUNDARY);
                            sb.append("\r\n");
                            sb.append("Content-Disposition: form-data; name=\""
                                    + entry.getKey() + "\"");
                            sb.append("\r\n");
                            sb.append("\r\n");
                            sb.append(entry.getValue());
                            sb.append("\r\n");
                            byte[] data = sb.toString().getBytes();
                            out.write(data);
                        }
                    }
                    out.write(end_data);
                    out.flush();
                    out.close();

                    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                        //另外，我们还希望接受返回的数据。
                        //1.打开读流
                        BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
                        StringBuilder builder = new StringBuilder();
                        String result;
                        //2.开始读入
                        while ((result = br.readLine()) != null) {
                            builder.append(result);
                        }
                        onResultFromWeb.onResult(builder.toString());
                    }

                } catch (Exception mE) {
                    mE.printStackTrace();
                    onResultFromWeb.onResult("");
                }
            }
        }).start();


    }


    /**
     * Function  :   封装请求体信息
     * Param     :   params请求体内容，encode编码格式
     */
    private static byte[] getRequestBodyData(Map<String, String> params, String encode) {
        StringBuilder stringBuffer = new StringBuilder();        //存储封装好的请求体信息
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                stringBuffer.append(entry.getKey())
                        .append("=")
                        .append(URLEncoder.encode(entry.getValue(), encode))
                        .append("&");
            }
            stringBuffer.deleteCharAt(stringBuffer.length() - 1);    //删除最后的一个"&"
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuffer.toString().getBytes();
    }


}
